#!/usr/bin/python
"""
we need to process these messages:
[1]  FROM is in whitelist
AND
[2] TO contains myplus OR [3] SUBJECT starts with "--"

todo:
[ ] handle fowarded file
[ ] handle fromlist validation
[ ] configure for +omnifocus?

"""
import imaplib
import time
import os

# configuration
#myplus='+omnifocus@'
#myfromlist=[
#    'mh@pixar.com',
#    #'markh@markharrison.net',
#    #'marhar@gmail.com'
#]

# extracted from:
# /Applications/ztools/OmniFocus.app/Contents/Resources/MailAction.applescript
osascript="""
tell application "OmniFocus"
    tell default document
        parse tasks with transport text "%s" as single task False
    end tell
end tell
"""

def imapserver():
    global myserver
    globals={}
    x={}
    execfile(os.environ['HOME']+'/.imap',globals,x)
    m=imaplib.IMAP4(x['server'])
    m.login(x['login'],x['passwd'])
    return m

def process(guts):
    """process by sending to omnifocus by invoking osascript"""
    import os
    script=osascript%(guts)
    (fd,res1,res2)=os.popen3('/usr/bin/osascript')
    fd.write(script)
    fd.close()
    res1.read()
    res2.read()
    res1.close()
    res2.close()

def dobody(pkg):
    """process the body of one message"""
    text= pkg[1][0][1]
    text=text.replace("\r",'')
    ix=text.find('\n\n')
    body=text[ix+2:]
    for line in text.split('\n'):
        if line.startswith('Subject:'):
            subj=line.strip()
            ix=subj.find(':')
            subj=subj[ix+2:]
            break
    guts=subj+'\n'+body.rstrip()
    guts=guts.replace('"','\\"')
    if guts.startswith('--'):
        print 'processing ---------------------------------------------------'
        print guts
        process(guts)
        domove=True
    else:
        domove=False
    return domove

def do1():
    """make one pass of the INBOX"""

    print '================================================ do1'
    m=imapserver()
    m.select('INBOX')

    # i thought imap supported nested and/or, but can't figure out how
    #if len(myfromlist)==1:
    #    fromclause='(FROM "%s")'%(myfromlist[0])
    #    searchclause='AND (TO "%s") %s'%(myplus,fromclause)
    #else:
    #    fromclause='OR'
    #    for i in myfromlist:
    #        fromclause+=' (FROM "%s")'%(i)
    #    searchclause='AND (TO "%s") (%s)'%(myplus,fromclause)

    ### get +omnifocus
    ##searchclause='(TO "%s")'%(myplus)
    ##x=m.search(None,searchclause)
    ##print 'x=',x

    # get "--"
    searchclause='(SUBJECT "--")'
    x=m.search(None,searchclause)

    for n in x[1][0].split():
        body=m.fetch(n,'(RFC822)')
        # move out of inbox to save folder
        # dont do this for now, since we might be sending to
        # each other and we want to get a notification
        if dobody(body) == True:
             zz=1
             do_move=True
             if do_move:
                 m.copy(n,'a-omnifocus')
                 m.store(n,'+FLAGS','\\Deleted')

    m.close()
    m.logout()

def doloop():
    """process the inbox repeatedly"""
    doit=True
    while doit:
        do1()
        doit=False #uncomment for oneshot testing
        time.sleep(20)

doloop()

notes="""
omnifocus combines message and body, then supports this syntax:
	-- action1
	notes for action 1
	-- action2
	notes for action 2

	-- action
		> project
		:: project
		# due date
		# sart date # due date
		$ duration
		// note

	-- Action 3 > Project 1 @ Context 1 // Same-line notes
	-- Action 4 #friday // Due Friday, because I only entered one date
	-- Action 5 #monday #friday // Starts Monday; due Friday.
	-- Action 6 #monday # // Starts Monday; no due date.
	-- Action 7 :: Project 3 // colons work in place of greater-than sign
	--Action8>p2@c2#2d$5m//no spaces needed, nor full names
"""

